package net.dreamlu.rapid;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.io.FileUtils;

import jetbrick.template.utils.PathUtils;
import net.dreamlu.rapid.helper.JetbrickHelper;
import net.dreamlu.rapid.model.DBColumn;
import net.dreamlu.rapid.model.DBTable;
import net.dreamlu.rapid.util.DBUtils;
import net.dreamlu.rapid.util.PropUtils;
import net.dreamlu.rapid.util.StrUtils;

/**
 * 自动生成部分，主程序
 * @author L.cm
 * email: 596392912@qq.com
 * site:http://www.dreamlu.net
 * @date 2014年9月10日 上午9:45:24
 */
public class RapidMain {

	/**
	 * 主方法，用于生成项目基础，*注意*使用前对整个项目 执行==> run as -> maven install
	 * @param args
	 * @throws SQLException
	 * @throws IOException 
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws SQLException, IOException, InterruptedException {
		// 注入配置文件
		Properties props    = PropUtils.loadProp("rapid.properties");
		// 默认包
		String basePkg      = props.getProperty("base.package");
		String pkgDir       = StrUtils.pkgToPath(basePkg);
		// 模板目录
		String templatePath = props.getProperty("template.path");
		// 输出目录
		String outRoot      = props.getProperty("outRoot");
		// 注入数据源
		DBUtils.initDataSource(props);
		// 获取表结构
		List<DBTable> tables = DBUtils.tables();

//		### 3.2 配置参数说明
//		|参数名称|类型|说明|
//		|:----| :---- | :----|
//		|`autofocus`|`boolean`|编辑器初始后是否默认获取焦点。 默认 `false`|

		StringBuilder tableInfo = new StringBuilder();
		String sqlName;
		for (DBTable dbTable : tables) {
			sqlName = dbTable.getSqlName();
			tableInfo.append("### ").append(sqlName).append('\n');
			tableInfo.append("|列名|类型|长度|注释|").append('\n');
			tableInfo.append("|:----| :---- | :----| :----|").append('\n');
			// 列名，类型，长度，注释
			for (DBColumn column : dbTable.getColumns()) {
				tableInfo.append("|").append(column.name)
						 .append("|").append(column.type)
						 .append("|").append(column.size)
						 .append("|").append(column.remarks)
						 .append("|").append('\n');
			}
			tableInfo.append('\n');
		}
		// 数据字典信息生成
		String doc = RapidMain.class.getResource("").getPath().split("target")[0].concat("database") + File.separator + "doc.md";
		FileUtils.writeStringToFile(new File(doc), tableInfo.toString(), "UTF-8");

		// 配置模板
		Properties jetbrickProp = PropUtils.loadProp("jetbrick-template.properties");
		JetbrickHelper helper = new JetbrickHelper().init(jetbrickProp);

		// 参数传递
		Map<String, Object> context = new HashMap<String, Object>();
		context.put("tables", tables);
		// 渲染模板
		context.put("basePkg", basePkg);
		context.put("pkgDir", pkgDir);
		context.put("now", new Date());
		// TODO L.cm 待完善
		generate(templatePath, outRoot, helper, context);

		// 生成model
		generateModel(tables, templatePath, outRoot, helper, context);
	}

	/**
	 * 生成model
	 * @param tables
	 * @param templatePath
	 * @param outRoot
	 * @param helper
	 * @param context
	 */
	private static void generateModel(List<DBTable> tables, String templatePath, String outRoot,
			JetbrickHelper helper, Map<String, Object> context) {
		// 项目所在目录
		String currentPath = PathUtils.getCurrentPath();
		String outPath = currentPath + outRoot;
		for (DBTable dbTable : tables) {
			String fileName = "/${className}.java";
			// 设置table的数据
			context.put("table", dbTable);
			context.put("className", dbTable.getClassName());
			String outFileName = helper.render(context, fileName);
			helper.render(context, fileName, outPath + File.separatorChar + outFileName);
		}
	}

	/**
	 * 生成的主方法
	 */
	public static void generate(String templatePath, String outRoot, JetbrickHelper helper, Map<String, Object> context) {
		// 项目所在目录
		String currentPath = PathUtils.getCurrentPath();
		// 先删除outRoot
		String outPath = currentPath + outRoot;
		File fileOut = new File(outPath);
		FileUtils.deleteQuietly(fileOut);
		fileOut.mkdirs();
		// 先删除outRoot
		File fileTemp = new File(currentPath + templatePath);
		renderTemp(fileTemp, helper, context, outPath);
	}

	/**
	 * 递归——渲染模板
	 */
	public static void renderTemp(File fileTemp, JetbrickHelper helper, Map<String, Object> context, String outPath) {
		File[] fileArray = fileTemp.listFiles(ExcludeFilter(".include"));
		for (File file : fileArray) {
			if(file.isDirectory()) {
				renderTemp(file, helper, context, outPath);
			} else {
				String fileName = file.getName();
				String outFileName = helper.render(context, fileName);
				helper.render(context, fileName, outPath + File.separatorChar + outFileName);
			}
		}
	}

	/**
	 * 排除指定后缀的文件 “.xxx”
	 * @param fileName
	 * @return
	 */
	private static FilenameFilter ExcludeFilter(String... fileName) {
		final String[] _fileName = fileName;
		return new FilenameFilter() {
			public boolean accept(File file, String name) {
				boolean ret = true;
				for (String string : _fileName) {
					if (!ret) break;
					ret = name.indexOf(string) == -1;
				}
				return ret;
			}
		};
	}
}
